package cn.avalon.service.impl;

import cn.avalon.domain.Product;
import cn.avalon.domain.PurchaseApply;
import cn.avalon.domain.Stock;
import cn.avalon.domain.StockWarningLog;
import cn.avalon.dto.StockDto;
import cn.avalon.enums.GlobalErrorCode;
import cn.avalon.exception.GlobalCustomException;
import cn.avalon.feign.ProductService;
import cn.avalon.feign.PurchaseService;
import cn.avalon.mapper.StockMapper;
import cn.avalon.properties.StockThresholdProperties;
import cn.avalon.result.JSONResult;
import cn.avalon.service.IStockService;
import cn.avalon.service.IStockWarningLogService;
import cn.avalon.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;


/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author qinjie
 * @since 2022-09-29
 */
@Service
public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements IStockService {

    @Autowired
    private ProductService productService;

    @Autowired
    private StockThresholdProperties stockThresholdProperties;

    @Autowired
    private IStockWarningLogService stockWarningLogService;

    @Autowired
    private PurchaseService purchaseService;

    @Override
    public void operate(StockDto stockDto) {
        Stock stock = selectStock(stockDto.getProductId());
        // 判断是出库还是入库
        if (stockDto.getState() == 0) { // 入库
            // 判断仓库中是否有该商品
            if (stock == null) { // 仓库中没有，新建
                stock = new Stock();
                stock.setProductId(stockDto.getProductId()); // 设置商品id
                stock.setCount(stockDto.getCount()); // 设置数量
                stock.setCreateTime(new Date()); // 设置时间
                // 通过id查询商品信息【信息被放在jsonResult.getData()中，需要转格式】
                JSONResult jsonResult = productService.get(stockDto.getProductId());
                // 1.判断是否成功
                AssertUtil.isTrue(jsonResult.isSuccess(), GlobalErrorCode.SERVICE_ERROR);
                Object data = jsonResult.getData();
                // 2.判断是否有商品信息
                AssertUtil.isNotNull(data, GlobalErrorCode.NULL);
                String jsonString = JSONObject.toJSONString(data); // 将data转成json格式字符串
                Product product = JSON.parseObject(jsonString, Product.class); // 将字符串转换为对应类型的对象
                stock.setProductName(product.getProductName()); // 设置商品名字
                stock.setTypeId(product.getTypeId()); // 设置商品类型
                insert(stock);
            } else { // 仓库中有，修改
                stock.setCount(stock.getCount() + stockDto.getCount());
                updateById(stock);
            }
        } else { // 出库
            Integer count = stock.getCount();
            // 1.判断仓库是否存在该商品
            AssertUtil.isNotNull(stock, GlobalErrorCode.NOT_FIND);
            // 2.判断库存是否充足
            if (count < stockDto.getCount()) { // 库存不足
                // 2.1判断库存是否到达阈值【这里会重复发送申请】
                Date date = new Date();
                if (count < stockThresholdProperties.getThreshold()) { // 小于阈值
                    StockWarningLog stockWarningLog = new StockWarningLog(); // 创建警告日志
                    BeanUtils.copyProperties(stock, stockWarningLog); // 调用工具类传入【商品id，商品名称，商品数量】
                    stockWarningLog.setInfo(stock.getProductName() + "库存不足了，请及时采购！"); // 设置信息
                    stockWarningLog.setCreateTime(date); // 设置时间
                    stockWarningLog.setCurrentCount(stock.getCount()); // 设置数量
                    stockWarningLogService.insert(stockWarningLog); // 新增
                    // 创建采购申请
                    PurchaseApply purchaseApply = new PurchaseApply();
                    BeanUtils.copyProperties(stock, purchaseApply); // 调用工具类传入【商品id，商品名称】
                    purchaseApply.setCount(100); // 设置申请数量
                    purchaseApply.setStatus(0); // 设置待审批
                    purchaseService.saveOrUpdate(purchaseApply); // 调用接口申请

                }
                // 大于阈值，小于需求
                throw new GlobalCustomException("库存不足，出库失败！");
            } else { // 库存充足
                stock.setCount(count - stockDto.getCount());
                updateById(stock); // 修改信息
                // 判断库存是否小于阈值 @TODO 没做小于阈值判断
                PurchaseApply purchaseApply = new PurchaseApply();
                BeanUtils.copyProperties(stock, purchaseApply);
                purchaseApply.setCreateTime(new Date());
                purchaseApply.setCount(100);
                purchaseApply.setStatus(0);
                purchaseService.saveOrUpdate(purchaseApply);
                throw new GlobalCustomException("库存不足，出库失败！");
            }
        }
    }

    /**
     * 通过商品id查询库存
     * @param productId
     * @return
     */
    private Stock selectStock(Long productId) {
        Wrapper<Stock> wrapper = new EntityWrapper();
        wrapper.eq("product_id", productId);
        return selectOne(wrapper);
    }
}
